package com.atues.thread.future;

import java.util.concurrent.*;
import java.util.stream.*;

public class CompletableFutureExceptionHandlingDemo {

    // 模拟可能失败的任务
    private static CompletableFuture<String> simulateTask(String name, boolean shouldFail) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(500); // 模拟耗时操作
                if (shouldFail) {
                    throw new RuntimeException(name + " failed!");
                }
                return name + " succeeded";
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }

    // 1. whenComplete示例
    public static void whenCompleteExample() {
        simulateTask("Task1", true)
            .whenComplete((result, ex) -> {//第一个是成功返回的参数，第二个是失败返回的参数；
                if (ex != null) {
                    System.out.println("[whenComplete] Exception caught: " + ex.getMessage());
                } else {
                    System.out.println("[whenComplete] Result: " + result);
                }
            })
            .join(); // 触发执行
    }

    // 2. exceptionally示例
    public static void exceptionallyExample() {
        String result = simulateTask("Task2", true)
            .exceptionally(ex -> {
                //当CompletableFuture执行过程中抛出异常时，捕获异常并提供替代结果（类似try-catch中的恢复逻辑）
                System.out.println("[exceptionally] Recovering from: " + ex.getMessage());
                return "Fallback value";
            })
            .join();
        System.out.println("[exceptionally] Final result: " + result);
    }

    // 3. handle示例
    public static void handleExample() {
        String result = simulateTask("Task3", false)
            .handle((res, ex) -> {
                if (ex != null) {
                    System.out.println("[handle] Handling exception: " + ex.getMessage());
                    return "Recovered";
                }
                return res.toUpperCase(); // 正常处理
            })
            .join();
        System.out.println("[handle] Final result: " + result);
    }

    // 4. allOf统一处理多个任务异常
    public static void allOfExample() {
        // 创建三个异步任务，其中任务B会故意失败
        CompletableFuture<String> future1 = simulateTask("A", false);
        CompletableFuture<String> future2 = simulateTask("B", true); // 这个任务会抛出异常
        CompletableFuture<String> future3 = simulateTask("C", false);

        // 使用allOf组合所有任务，返回一个新的CompletableFuture<Void>
        // 当所有任务完成时（无论成功或失败），这个新future会完成
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3);

        // 为组合后的future添加异常处理
        // 注意：这不会阻止异常传播，只是添加了一个回调
        allFutures.exceptionally(ex -> {
            System.out.println("[allOf] Some task failed: " + ex.getMessage());
            return null;
        });

        // 获取各任务结果
        try {
            // 等待所有任务完成（阻塞当前线程）
            allFutures.join(); // 这行会抛出CompletionException，因为future2失败了

            // 以下代码实际上不会执行，因为上面的join()已经抛出了异常
            System.out.println("Task A: " + future1.join());
            System.out.println("Task C: " + future3.join());
            future2.join(); // 这行也不会执行
        } catch (CompletionException e) {
            // 捕获到异常后直接打印，没有继续处理其他任务的结果
            System.out.println("[allOf] Caught exception from individual task: " + e.getCause().getMessage());
        }
    }

    public static void main(String[] args) {
//        System.out.println("=== whenComplete ===");
//        whenCompleteExample();

        System.out.println("\n=== exceptionally ===");
        exceptionallyExample();

        System.out.println("\n=== handle ===");
        handleExample();

        System.out.println("\n=== allOf ===");
        allOfExample();
    }
}